<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>

    <link
      rel="stylesheet"
      type="text/css"
      href="./Cesium/Widgets/widgets.css"
    />
    <script type="text/javascript" src="./cesium/Cesium.js"></script>

    <style>
      body {
        margin: 0;
        padding: 0;
      }
    </style>
  </head>

  <body>
    <div id="cesiumcontainer" style="width: 100vw; height: 100vh"></div>

    <script>
      Cesium.Ion.defaultAccessToken =
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2ZTgxOGNhZC03NThmLTQ0NzMtOTNlYS1kNmM3YzlmZDU3NTMiLCJpZCI6MTI1NTY3LCJpYXQiOjE2NzY5MDI0MzJ9.ulIEz3NCh2cMEBiHrqIuv9I6icn5KTMMnBdy2wassoM";
      var viewer = new Cesium.Viewer("cesiumcontainer", {
        // 生成地形
        terrainProvider: Cesium.createWorldTerrain(),
        requestRenderMode: true, // 优化性能
        maximumRenderTimeChange: Infinity, // 优化性能
      });

      const add3DLine = (withOutline) => {
        const volume = []; // 管线
        const volume_outline = []; // 管线轮廓

        // 管线的横截面，radius半径，side_number几边形
        function computeCircle(radius, side_number) {
          const positions = [];
          for (let i = 0; i < side_number; i++) {
            const radians = Cesium.Math.toRadians(i * (360 / side_number)); // 360边形就是一个圆
            positions.push(
              new Cesium.Cartesian2(
                radius * Math.cos(radians),
                radius * Math.sin(radians)
              )
            );
          }
          return positions;
        }

        mapData.features.forEach((feature, index) => {
          const positions = feature.geometry.coordinates[0];
          volume.push(
            new Cesium.GeometryInstance({
              geometry: new Cesium.PolylineVolumeGeometry({
                polylinePositions: Cesium.Cartesian3.fromDegreesArrayHeights(
                  handleFromDegreesArrayHeight(positions, 0)
                ),
                shapePositions: computeCircle(0.5, 4),
              }),
            })
          );
          if (withOutline) {
            volume_outline.push(
              new Cesium.GeometryInstance({
                geometry: new Cesium.PolylineVolumeOutlineGeometry({
                  polylinePositions: Cesium.Cartesian3.fromDegreesArrayHeights(
                    handleFromDegreesArrayHeight(positions, 0)
                  ),
                  shapePositions: computeCircle(0.5, 4),
                }),
                attributes: {
                  color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    new Cesium.Color(255 / 255, 255 / 255, 255 / 255, 1)
                  ),
                },
              })
            );
          }
        });

        let volume_color = {
          P4: new Cesium.Color.fromBytes(191, 0, 255, 1),
          P5: new Cesium.Color.fromBytes(0, 255, 255, 1),
          P6: new Cesium.Color.fromBytes(255, 0, 0, 1),
          "P6.2": new Cesium.Color.fromBytes(255, 0, 0, 1),
          P7: new Cesium.Color.fromBytes(255, 165, 0, 1),
          P8: new Cesium.Color.fromBytes(0, 255, 0, 1),
          other: new Cesium.Color.fromBytes(167, 89, 9, 1),
        };

        for (let key in volume) {
          let volume_primitives = new Cesium.Primitive({
            geometryInstances: volume[key],
            releaseGeometryInstances: false,
            appearance: new Cesium.EllipsoidSurfaceAppearance({
              material: new Cesium.Material({
                fabric: {
                  uniforms: {
                    image: surface_img,
                    color: volume_color[key],
                  },
                  source: `
								uniform vec4 color;

								czm_material czm_getMaterial(czm_materialInput materialInput)
								{
									czm_material material = czm_getDefaultMaterial(materialInput);
									vec2 st = materialInput.st;
									float s = st.s;
									float t = st.t;
									vec4 colorImage = texture2D(image, vec2(fract(s), t));
									material.diffuse = colorImage.rgb * color.rgb;
									return material;
								}
							`,
                },
              }),
            }),
          });
          viewer.scene.primitives.add(volume_primitives);
        }
        if (withOutline) {
          viewer.scene.primitives.add(
            new Cesium.Primitive({
              geometryInstances: volume_outline,
              appearance: new Cesium.PerInstanceColorAppearance({
                flat: true,
                renderState: {
                  lineWidth: 1.0,
                },
              }),
            })
          );
        }
      };
    </script>
  </body>
</html>
